//备注：拷贝代码请加上作者信息
//作者：王海涛
//邮箱：1126471088@qq.com
//版本：V0.1.1
/********************************************************
    说明：
    1、ADC独立模式已支持。
    2、双ADC模式暂未支持。
    3、注入模式暂未支持。
    4、支持阻塞模式、中断模式、DMA模式。
    5、基于STM32F10X标准库V3.6.0
**********************************************************/
#ifndef __ADC_BSP_H__
#define __ADC_BSP_H__

#include "stm32f10x.h"
#include "stm32f10x_adc.h"
#include "misc.h"
#include "../GPIO_BSP/gpio_bsp.h"
#include "../DMA_BSP/dma_bsp.h"

/* STM32VET6 ADC通道对应的GPIO
    ADC通道       ADC1           ADC2       ADC3
    ADC_CH0       PA0            PA0        PA0
    ADC_CH1       PA1            PA1        PA1
    ADC_CH2       PA2            PA2        PA2
    ADC_CH3       PA3            PA3        PA3
    ADC_CH4       PA4            PA4        NA
    ADC_CH5       PA5            PA5        NA
    ADC_CH6       PA6            PA6        NA
    ADC_CH7       PA7            PA7        NA
    ADC_CH8       PB0            PB0        NA
    ADC_CH9       PB1            PB1        内部Vss
    ADC_CH10      PC0            PC0        PC0
    ADC_CH11      PC1            PC1        PC1
    ADC_CH12      PC2            PC2        PC2
    ADC_CH13      PC3            PC3        PC3
    ADC_CH14      PC4            PC4        内部Vss
    ADC_CH15      PC5            PC5        内部Vss
    ADC_CH16      内部温度传感器 内部Vss    内部Vss
    ADC_CH17      内部Vrefint    内部Vss    内部Vss
*/

/*ADC号枚举*/
typedef enum
{
    ADC1_ADC2 = 0,    //双ADC模式使用
    ADC_1 = ADC1_BASE,
    ADC_2 = ADC2_BASE,
    ADC_3 = ADC3_BASE,
}WHT_ADC_enum;

/*ADC通道*/
typedef enum
{
    ADC_CH0  = ADC_Channel_0,
    ADC_CH1  = ADC_Channel_1,
    ADC_CH2  = ADC_Channel_2,
    ADC_CH3  = ADC_Channel_3,
    ADC_CH4  = ADC_Channel_4,
    ADC_CH5  = ADC_Channel_5,
    ADC_CH6  = ADC_Channel_6,
    ADC_CH7  = ADC_Channel_7,
    ADC_CH8  = ADC_Channel_8,
    ADC_CH9  = ADC_Channel_9,
    ADC_CH10 = ADC_Channel_10,
    ADC_CH11 = ADC_Channel_11,
    ADC_CH12 = ADC_Channel_12,
    ADC_CH13 = ADC_Channel_13,
    ADC_CH14 = ADC_Channel_14,
    ADC_CH15 = ADC_Channel_15,
    ADC_CH16 = ADC_Channel_TempSensor,
    ADC_CH17 = ADC_Channel_Vrefint,
}WHT_ADC_Channel_enum;

/*ADC时钟源分频枚举*/
typedef enum
{
    APB2_Div2 = RCC_PCLK2_Div2,//if APB2=72Mhz ADC_CLK Max 14Mhz
    APB2_Div4 = RCC_PCLK2_Div4,
    APB2_Div6 = RCC_PCLK2_Div6,
    APB2_Div8 = RCC_PCLK2_Div8,
}WHT_ADC_Clk_enum;

/*ADC采样时间枚举*/
typedef enum
{
    ADC_Clk_Time_1_5   = ADC_SampleTime_1Cycles5,  //1.5个ADC时钟周期
    ADC_Clk_Time_7_5   = ADC_SampleTime_7Cycles5,  //7.5个ADC时钟周期
    ADC_Clk_Time_13_5  = ADC_SampleTime_13Cycles5, //13.5个ADC时钟周期
    ADC_Clk_Time_28_5  = ADC_SampleTime_28Cycles5, //28.5个ADC时钟周期
    ADC_Clk_Time_41_5  = ADC_SampleTime_41Cycles5, //41.5个ADC时钟周期
    ADC_Clk_Time_55_5  = ADC_SampleTime_55Cycles5, //55.5个ADC时钟周期
    ADC_Clk_Time_71_5  = ADC_SampleTime_71Cycles5, //71.5个ADC时钟周期
    ADC_Clk_Time_239_5 = ADC_SampleTime_239Cycles5,//239.5个ADC时钟周期
}WHT_ADC_Sample_Time_enum;

/*双ADC模式的第一个ADC，必须是ADC1
双ADC模式的第二个ADC，必须是ADC2*/
typedef enum
{ 
    Independent            = ADC_Mode_Independent,           //独立模式
    RegInjecSimult         = ADC_Mode_RegInjecSimult,        //混合的同步规则+注入同步模式
    RegSimult_AlterTrig    = ADC_Mode_RegSimult_AlterTrig,   //混合的同步规则+交替触发模式
    InjecSimult_FastInterl = ADC_Mode_InjecSimult_FastInterl,//混合同步注入+快速交叉模式
    InjecSimult_SlowInterl = ADC_Mode_InjecSimult_SlowInterl,//混合同步注入+慢速交叉模式
    InjecSimult            = ADC_Mode_InjecSimult,           //注入同步模式
    RegSimult              = ADC_Mode_RegSimult,             //规则同步模式，ADC1 ADC2通道的采样时间需要一致
    FastInterl             = ADC_Mode_FastInterl,            //快速交叉模式
    SlowInterl             = ADC_Mode_SlowInterl,            //慢速交叉模式
    AlterTrig              = ADC_Mode_AlterTrig,             //交替触发模式
}WHT_ADC_Work_Mode_enum;

/*ADC规则通道触发转换信号源*/
typedef enum
{
    /*ADC1 ADC2的触发信号源*/
    Timer1_CC1_Event  = ADC_ExternalTrigConv_T1_CC1, //定时器1的输入捕获/输出比较事件
    Timer1_CC2_Event  = ADC_ExternalTrigConv_T1_CC2, //定时器1的输入捕获/输出比较事件
    Timer2_CC2_Event  = ADC_ExternalTrigConv_T2_CC2, //定时器2的输入捕获/输出比较事件
    Timer3_TRGO_Event = ADC_ExternalTrigConv_T3_TRGO,//定时器3的触发输出事件
    Timer4_CC4_Event  = ADC_ExternalTrigConv_T4_CC4, //定时器4的输入捕获/输出比较事件
    EXTI_Line11_OR_TIM8_TRGO_Event = ADC_ExternalTrigConv_Ext_IT11_TIM8_TRGO,//外部中断线11或定时器8的触发输出事件
    /*ADC1 ADC2 ADC3的触发信号源*/
    Timer1_CC3_Event  = ADC_ExternalTrigConv_T1_CC3, //定时器1的输入捕获/输出比较事件
    Extern_Event_None = ADC_ExternalTrigConv_None,   //无外部事件触发转换，用户需手动触发转换
    /*ADC3的触发信号源*/
    Timer3_CC1_Event  = ADC_ExternalTrigConv_T3_CC1, //定时器3的输入捕获/输出比较事件
    Timer2_CC3_Event  = ADC_ExternalTrigConv_T2_CC3, //定时器2的输入捕获/输出比较事件
    Timer8_CC1_Event  = ADC_ExternalTrigConv_T8_CC1, //定时器8的输入捕获/输出比较事件
    Timer8_TRGO_Event = ADC_ExternalTrigConv_T8_TRGO,//定时器8的触发输出事件
    Timer5_CC1_Event  = ADC_ExternalTrigConv_T5_CC1, //定时器5的输入捕获/输出比较事件
    Timer5_CC3_Event  = ADC_ExternalTrigConv_T5_CC3, //定时器5的输入捕获/输出比较事件
}WHT_ADC_Trig_Event_enum;

/*ADC注入通道触发转换信号源*/
typedef enum
{
    /*ADC1 ADC2的触发信号源*/
    J_Timer2_TRGO_Event  = ADC_ExternalTrigInjecConv_T2_TRGO,//定时器1的输入捕获/输出比较事件
    J_Timer2_CC1_Event   = ADC_ExternalTrigInjecConv_T2_CC1, //定时器1的输入捕获/输出比较事件
    J_Timer3_CC4_Event   = ADC_ExternalTrigInjecConv_T3_CC4, //定时器2的输入捕获/输出比较事件
    J_Timer4_TRGO_Event  = ADC_ExternalTrigInjecConv_T4_TRGO,//定时器3的触发输出事件
    J_EXTI_Line15_OR_Timer8_CC4_Event = ADC_ExternalTrigInjecConv_Ext_IT15_TIM8_CC4,//定时器4的输入捕获/输出比较事件
    /*ADC1 ADC2 ADC3的触发信号源*/
    J_Timer1_TRGO_Event  = ADC_ExternalTrigInjecConv_T1_TRGO,//定时器1的输入捕获/输出比较事件
    J_Timer1_CC4_Event   = ADC_ExternalTrigInjecConv_T1_CC4, //定时器1的输入捕获/输出比较事件
    J_Extern_Event_None  = ADC_ExternalTrigInjecConv_None,   //无外部事件触发转换，用户需手动触发转换
    /*ADC3的触发信号源*/
    J_Timer4_CC3_Event   = ADC_ExternalTrigInjecConv_T4_CC3, //定时器3的输入捕获/输出比较事件
    J_Timer8_CC2_Event   = ADC_ExternalTrigInjecConv_T8_CC2, //定时器2的输入捕获/输出比较事件
    J_Timer8_CC4_Event   = ADC_ExternalTrigInjecConv_T8_CC4, //定时器8的输入捕获/输出比较事件
    J_Timer5_TRGO_Event  = ADC_ExternalTrigInjecConv_T5_TRGO,//定时器8的触发输出事件
    J_Timer5_CC4_Event   = ADC_ExternalTrigInjecConv_T5_CC4, //定时器5的输入捕获/输出比较事件
}WHT_ADC_J_Trig_Event_enum;

typedef struct
{
    void* Cache_New_Addr;//缓存最新指向的缓存地址
    FlagStatus Busy_Flag;//忙碌标志,切记只读
}WHT_ADC_Info_t;

/*ADC 通道 转换顺序 采样时间结构体*/
typedef struct
{
    /*ADC通道转换顺序参考此结构体数组下标的顺序，最大支持16个配置数组*/
    /*使用范例如 WHT_ADC_Channel_Config channel[4]*/
    WHT_ADC_Channel_enum Channel;        //通道
    WHT_ADC_Sample_Time_enum Sample_Time;//通道采样时间
}WHT_ADC_Channel_Config;

/*ADC 配置结构体*/
typedef struct
{
    WHT_ADC_enum Name;                     //ADC号
    WHT_ADC_Clk_enum Clk_Div;              //时钟分频因子
    WHT_ADC_Work_Mode_enum Mode;           //工作模式选择，ADC2和ADC3只能选择独立模式
    unsigned char Channel_Count;           //采集通道数 is 1 to 16
    WHT_ADC_Trig_Event_enum ExternalTrigConv;//转换触发信号选择,一般情况下选择软件触发转换
    unsigned char PreemptionPriority;      //抢占优先级
    unsigned char SubPriority;             //子优先级
    WHT_ADC_Channel_Config* Channel_Config;//ADC通道配置
}WHT_ADC_Config_t;

typedef struct
{
    unsigned short Rx_Count; //每个通道接收个数
    unsigned short* Rx_Buf;  //数据缓存，数组的深度为为通道采集的值，行为通道号，列为ADC号。范例4个通道，每个通道采集8个数据unsigned short ADC_Buf[8][4][1]表示独立模式,ADC_Buf[8][4][2]表示双ADC模式
    volatile const WHT_ADC_Info_t* Info;//ADC状态信息
    void* Private_Data;//私有数据
}WHT_ADC_Cache_t;

typedef struct
{
    ErrorStatus (*WHT_Register)(const WHT_ADC_Config_t* config, const WHT_ADC_Cache_t* cache);//注册
    void (*WHT_Config)(const WHT_ADC_Config_t* config, const WHT_ADC_Cache_t* cache);//每个设备可自行配置
    void (*WHT_Receive)(const WHT_ADC_Cache_t* cache);              //启动接收数据非中断版
    void (*WHT_Interrupt_Receive)(const WHT_ADC_Cache_t* cache);    //启动接收数据中断版
    void (*WHT_DMA_Receive)(const WHT_ADC_Cache_t* cache);          //启动接收数据DMA版
    void (*WHT_End_Interrupt_Receive)(const WHT_ADC_Cache_t* cache);//结束中断接收数据
    void (*WHT_End_DMA_Receive)(const WHT_ADC_Cache_t* cache);      //结束DMA接收数据
}WHT_ADC_BSP_t;

/*全局常量*/
extern const WHT_ADC_BSP_t WHT_ADC_BSP;


// 双模式时，ADC1和ADC2转换的数据都存放在ADC1的数据寄存器，
// ADC1的在低十六位，ADC2的在高十六位

#endif // !__ADC_BSP_H__
